package com.kk.base.service.admin;

import com.kk.base.bean.PageBean;
import com.kk.base.dao.admin.BuyOffDao;
import com.kk.base.dao.admin.UserDao;
import com.kk.base.dao.home.ExpressMailOrderDao;
import com.kk.base.dao.admin.ProcessRecordsDao;
import com.kk.base.entity.admin.BuyOff;
import com.kk.base.entity.admin.ProcessRecords;
import com.kk.base.entity.admin.User;
import com.kk.base.entity.common.ExpressMailOrderStatus;
import com.kk.base.entity.home.ExpressMailOrder;
import com.kk.base.util.SessionUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

@Service
public class ProcessRecordsService {

    @Autowired
    private ProcessRecordsDao processRecordsDao;

    @Autowired
    private ExpressMailOrderDao expressMailOrderDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private BuyOffDao buyOffDao;

    /**
     * 网点发货
     *
     * @param expressMailOrderId
     * @param nextBranchId
     * @param orderStatus
     * @param travelPosition
     * @return
     */
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRES_NEW, timeout = 15)
    public Integer ChangeStatusSaveProcess(Long expressMailOrderId, Long nextBranchId,
                                           int orderStatus, int travelPosition) {
        User loginedUser = SessionUtil.getLoginedUser();
        Integer abnormalJudgment = 0;
        try {


            ExpressMailOrder expressMailOrder = expressMailOrderDao.find(expressMailOrderId);
            expressMailOrder.setOrderStatus(orderStatus);

            ExpressMailOrder saveExpressMailOrder = expressMailOrderDao.save(expressMailOrder);

            User nextBranchUser = userDao.find(nextBranchId);

            ProcessRecords processRecords = new ProcessRecords();
            processRecords.setExpressMailOrder(saveExpressMailOrder);
            processRecords.setReceivedBranch(loginedUser);
            processRecords.setNextBranch(nextBranchUser);
            processRecords.setTravelPosition(travelPosition);
            processRecordsDao.save(processRecords);

        } catch (Exception e) {
            abnormalJudgment = 1;
        }

        return abnormalJudgment;
    }


    /**
     * 运输中途添加记录
     *
     * @param processRecordsId
     * @param userId
     * @return
     */
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRES_NEW, timeout = 15)
    public Integer transportation(Long processRecordsId, Long userId) {
        User loginedUser = SessionUtil.getLoginedUser();
        Integer abnormalJudgment = 0;
        try {
            ProcessRecords processRecords = processRecordsDao.find(processRecordsId);
            processRecords.setOperation(ProcessRecords.HAVE_HANDLED);
            processRecordsDao.save(processRecords);

            ProcessRecords processRecordsAdd = new ProcessRecords();
            processRecordsAdd.setReceivedBranch(loginedUser);
            processRecordsAdd.setNextBranch(userDao.find(userId));
            processRecordsAdd.setExpressMailOrder(processRecords.getExpressMailOrder());
            processRecordsAdd.setTravelPosition(ExpressMailOrderStatus.COMPLETED);
            processRecordsDao.save(processRecordsAdd);
        } catch (Exception e) {
            e.printStackTrace();
            abnormalJudgment = 1;
        }

        return abnormalJudgment;
    }


    /**
     * 分页查询发出流程列表
     *
     * @param pageBean
     * @return
     */
    public PageBean<ProcessRecords> findList(PageBean<ProcessRecords> pageBean, String waybillNumber) {

        Specification<ProcessRecords> specification = specification(ProcessRecords.NO_OPERATIONS, waybillNumber, ExpressMailOrderStatus.COMPLETED);
        Pageable pageable = PageRequest.of(pageBean.getCurrentPage() - 1, pageBean.getPageSize());
        Page<ProcessRecords> findAll = processRecordsDao.findAll(specification, pageable);
        pageBean.setContent(findAll.getContent());
        pageBean.setTotal(findAll.getTotalElements());
        pageBean.setTotalPage(findAll.getTotalPages());
        return pageBean;
    }


    /**
     * 分页查询完成流程列表
     *
     * @param pageBean
     * @return
     */
    public PageBean<ProcessRecords> findListByWaybillNumber(PageBean<ProcessRecords> pageBean, String waybillNumber) {
        Specification<ProcessRecords> specification = specification(ProcessRecords.NO_OPERATIONS, waybillNumber, ExpressMailOrderStatus.INTRANSIT);
        Pageable pageable = PageRequest.of(pageBean.getCurrentPage() - 1, pageBean.getPageSize());
        Page<ProcessRecords> findAll = processRecordsDao.findAll(specification, pageable);
        pageBean.setContent(findAll.getContent());
        pageBean.setTotal(findAll.getTotalElements());
        pageBean.setTotalPage(findAll.getTotalPages());
        return pageBean;
    }


    /**
     * 查询条件
     *
     * @param operation
     * @param waybillNumber
     * @return
     */
    private Specification<ProcessRecords> specification(Integer operation, String waybillNumber, Integer travelPosition) {
        User loginedUser = SessionUtil.getLoginedUser();

        Specification<ProcessRecords> specification = (Specification<ProcessRecords>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (null != operation) {
                predicates.add(criteriaBuilder.equal(root.get("operation"), operation));
            }

            predicates.add(criteriaBuilder.equal(root.get("nextBranch").get("id"), loginedUser.getId()));

            predicates.add(criteriaBuilder.equal(root.get("travelPosition"), travelPosition));

            if (!StringUtils.isEmpty(waybillNumber)) {
                predicates.add(criteriaBuilder.like(root.get("expressMailOrder").get("waybillNumber"), "%" + waybillNumber + "%"));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        return specification;
    }


    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public ProcessRecords find(Long id) {
        return processRecordsDao.find(id);
    }

    /**
     * 保存/编辑
     *
     * @param processRecords
     * @return
     */
    public ProcessRecords save(ProcessRecords processRecords) {
        return processRecordsDao.save(processRecords);
    }


    /**
     * 确认收货派送
     *
     * @param id
     * @return
     */
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRES_NEW, timeout = 15)
    public Integer delivery(Long id) {
        Integer abnormalJudgment = 0;
        User loginedUser = SessionUtil.getLoginedUser();
        try {
            ProcessRecords processRecords = processRecordsDao.find(id);
            processRecords.setOperation(ProcessRecords.HAVE_HANDLED);
            processRecords.setTravelPosition(ExpressMailOrderStatus.INTRANSIT);
            processRecordsDao.save(processRecords);
            ExpressMailOrder expressMailOrder = processRecords.getExpressMailOrder();
            expressMailOrder.setOrderStatus(ExpressMailOrderStatus.INTHEDELIVERY);
            ExpressMailOrder saveExpressMailOrder = expressMailOrderDao.save(expressMailOrder);

            BuyOff buyOff = new BuyOff();
            buyOff.setBuyOffUser(loginedUser);
            buyOff.setBuyOffExpressMailOrder(saveExpressMailOrder);
            buyOff.setStatus(BuyOff.CONFIRM_THE_DELIVERY);
            buyOffDao.save(buyOff);

        } catch (Exception e) {
            e.printStackTrace();
            abnormalJudgment = 1;
        }
        return abnormalJudgment;
    }

    /**
     * 根据订单ID查询
     * @param expressMailOrderId
     * @return
     */
    public List<ProcessRecords> findByExpressMailOrder_Id(Long expressMailOrderId){
        return processRecordsDao.findByExpressMailOrder_Id(expressMailOrderId);
    }

}
